iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0

今天我們會繼續使用隨機生成物件的Project來進行今天的解說!
Teleport 顧名思義就是順移,我們在虛擬實境中透過順移可以減少 Motion Sickness 的問題,也就是降低使用者在虛擬實境中暈眩的程度,所以目前在市面上很多遊戲、虛擬場景會透過 Teleport 的方式來幫助使用者快速移動到下個地點或是代替移動的方案等。幫助使用者更好在虛擬世界中移動,雖然缺點是會降低VR沉侵感,但利大於弊,這個Teleport移動方案可以增加在VR使用上的時間,比較不容易因為頭暈不適而簡短使用上的時間。
瞬移 Teleport 的概念在虛擬實境中非常簡單,所以接下來會進行簡單的實驗。

首先新增 LineRenderer

  1. 調整該 Width ,Material 就選擇 Default-Line。顏色就依自己喜好調整。

結果如下

  1. 回到之前撰寫的腳本GenerateObj.cs,新增 LineRenderer 物件到我們的程式中。
void Start() 
    {
        cu =rrentPosition = ChickenObj.position;
        lr = GetComponent<LineRenderer>();
        if(lr == null)
            lr = gameObject.AddComponent<LineRenderer>();
        lr.startWidth = 0.044f;
        lr.endWidth = 0.044f;
        lr.positionCount = 2;
    }
  1. 接著到我們隨機生成的兩個物件方法中。
void randomObj()
    {
        for(int i = 0; i < 2; i++)
        {
            int getAngle = Random.Range(0, angle.Length);
            int getDistance = Random.Range(0, distance.Length);
            float randomAngle = angle[getAngle];
            float randomDistance = distance[getDistance];   
            Debug.Log("Random Angle: " + randomAngle + ", Distance: " + randomDistance);
            Vector2 offset = new Vector2(Mathf.Sin(randomAngle * Mathf.PI/180.0f), Mathf.Cos(randomAngle * Mathf.PI/180.0f)) * randomDistance;
            Vector3 newPosition = new Vector3(currentPosition.x + offset.y, currentPosition.y ,currentPosition.z + offset.x);
            createGenerateList[i] = (GameObject)GameObject.Instantiate(generateObjModel, newPosition, Quaternion.identity);
        }
      
    }

首先新增一個 List 來儲存每一次新增的兩個物件。目的就是我要取得我要 Teleport 的位置。

List<GameObject> getCreateObj = new List<GameObject>();

接下來到隨機生成兩個物件的地方,去 Add 生成後的兩個物件。

void randomObj()
    {
        for(int i = 0; i < 2; i++)
        {
            int getAngle = Random.Range(0, angle.Length);
            int getDistance = Random.Range(0, distance.Length);
            float randomAngle = angle[getAngle];
            float randomDistance = distance[getDistance];   
            Debug.Log("Random Angle: " + randomAngle + ", Distance: " + randomDistance);
            Vector2 offset = new Vector2(Mathf.Sin(randomAngle * Mathf.PI/180.0f), Mathf.Cos(randomAngle * Mathf.PI/180.0f)) * randomDistance;
            Vector3 newPosition = new Vector3(currentPosition.x + offset.y, currentPosition.y ,currentPosition.z + offset.x);
            createGenerateList[i] = (GameObject)GameObject.Instantiate(generateObjModel, newPosition, Quaternion.identity);
            getCreateObj.Add(createGenerateList[i]);       // here get create obj
        }
      
    }
  1. 每次生成完兩個物件後就要去詢問 User 想要 Teleport 到哪個位置。所以我們要新增一個 User 是否回答的情況好讓我們去進行 判斷是否可以進行 Teleport。
bool askChooseObj = false;
void randomObj()
    {
        for(int i = 0; i < 2; i++)
        {
            int getAngle = Random.Range(0, angle.Length);
            int getDistance = Random.Range(0, distance.Length);
            float randomAngle = angle[getAngle];
            float randomDistance = distance[getDistance];   
            Debug.Log("Random Angle: " + randomAngle + ", Distance: " + randomDistance);
            Vector2 offset = new Vector2(Mathf.Sin(randomAngle * Mathf.PI/180.0f), Mathf.Cos(randomAngle * Mathf.PI/180.0f)) * randomDistance;
            Vector3 newPosition = new Vector3(currentPosition.x + offset.y, currentPosition.y ,currentPosition.z + offset.x);
            createGenerateList[i] = (GameObject)GameObject.Instantiate(generateObjModel, newPosition, Quaternion.identity);
            getCreateObj.Add(createGenerateList[i]);                    // get create obj
        }
      askChooseObj = true;
    }
  1. 接下來到控制的地方,這邊就是當生成完兩個隨機的 Target後會進入到詢問User 的狀態,所以askChooseObj 是 True 的狀態,我們知道 Unity在 Update中會不斷的執行,所以這時候我們可以透過當 askChooseObj == true 時強制其轉換到下一個詢問的狀態。
void Update() 
    {
        
        if(askChooseObj)
        {
            chooseTeleport();
        }else{
            if(Input.GetKeyDown("l"))
            {
                randomObj();  
            }
        }
        
    }
  1. 在 chooseTeleport 中我們會去先讓User 可以選擇要Teleport 的方位,所以會有 chooseId 去代表該Teleport 的位置,則 TrueSelect 是Player 選擇後決定好的位置。之後會取得該TrueSelect 並且讓其 User 的Postion 順移到選擇的 Target Point。
void chooseTeleport()
    {
        if(Input.GetKeyDown("q")){      // switch the target 
            Debug.Log("You choose the target!, Id: " + chooseId);
            trueSelect = chooseId;
            lr.SetPosition(0, ChickenObj.position);
            lr.SetPosition(1, getCreateObj[chooseId].transform.position);
            chooseId++;
            if(chooseId>=2){
                chooseId = 0;
            }
        }else if(Input.GetKeyDown("w"))  // select the target to teleport
        {
            //Debug.Log("You choose the target!, Id: " + chooseId);
            ChickenObj.position = getCreateObj[trueSelect].transform.position;
            getCreateObj.Clear();                                   // Remove all the store angle
            for(int i = 0; i < 2; i++)
            {
                Destroy(createGenerateList[i]);                     // Destroy the last two object
            }
            currentPosition = ChickenObj.position;                  // teleport to the target point
            askChooseObj = false;                                   // switch back to the random generate target object
            lr.SetPosition(0, ChickenObj.position);                 // not to show the line after teleport
        }

    }

這邊的功能有按下 q 代表進行切換選擇的角度,chooseId 就是 getCreateObj List 中的資料位址。而我們知道要將我們User與所選擇的 Teleport Point 透過 Line 連接起來,每當按下 q鍵的時候就會切換所選擇的 Teleport Point。所以說當 ChooseId ≥ 2 的時候就要換成 0。若按下 w 鍵後就會取得該當下的 trueSelect 來使其找尋到對的 Teleport Point 並且瞬移到該位置。最後要將所有剛剛儲存的資料的List 內的角度清空,與刪除掉剛剛在環境中的 Target Point 物件。

  1. 最後回到 Unity。將我們的 Main Camera 放置遠離該 User 一點。

  2. 執行來觀察結果八。

  • 首先按下 L 鍵,新增兩個隨機位置的物件。

  • 按下 Q 鍵可以切換選擇想要 Teleport 的位置

  1. 按下鍵盤 W 可以瞬移到該位置。這邊我瞬移到左側

  2. 再次按下 L 鍵,又可以隨機產生兩個新的 Teleport Point 。

結論

  1. 今天我們了解如何在虛擬實境中做瞬移。
  2. 透過判斷可以控制決定要處理哪個情境下的事情。
  3. 單一數量條件下,做到可來回切換不同選擇的功能。
  4. 把之前所練習的相關函數拿來做使用。

上一篇
Day8: Generate and Delete Random Position Object
下一篇
Day10: Image Progress Bar
系列文
Unity 基本功能實作與日常紀錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言